<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div>打开控制台查看内容</div>

    <script>


        //*******判断字符串传是否包含在另一个字符串中**********
        console.log('========断字符串传是否包含在另一个字符串中==========');
        // 判断字符串传是否包含在另一个字符串中 
        let s = 'Hello world'
        
        /* 参数字符串是否在原字符串的头部 返回布尔值 */
        console.log(s.startsWith('Hello')); // true

        /* 参数字符串是否在原字符串的尾部 返回布尔值 */
        console.log(s.endsWith('world'));  // true

        /* 字符串是否包含参数字符串 */
        console.log(s.includes('w'));  // true

        /* startsWith,endsWith,includes都支持第二个参数，表示开始搜索的位置 */
        let w = '东方不败'
        /* 索引从0开始 */
        console.log(w.startsWith('方',1));  // true
        console.log(w.endsWith('方',2));   // true
        /* includes第二个参数表示从指定下标开始向后寻找，返回布尔值 */
        console.log(w.includes('不败',2));  // true
        console.log(w.includes('不败',3));  // false


        console.log('========repeat()==========');
        //******实例方法： repeat() *********
        /* repeat方法返回新的字符串，并将原字符串重复 n 次 */
        let a = 'hello'
        console.log(a.repeat(3));   // hellohellohello 重复3次
        console.log('w'.repeat(2));  // ww 重复2次
        console.log(a.repeat(0));  // ""  字符串置空
        console.log(a.repeat(2.7)); // 如果是小数则取整  重复2次

        /* 如果是复数或者Infinity则报错 */
        // console.log(a.repeat(Infinity));
        // console.log(a.repeat(-1));
        console.log(a.repeat(-0.9)); // 如果是0~-1之间的小数，因为会取整，所以是0 ""
        console.log(a.repeat(NaN));  // NaN等于0   ""
        console.log('===');
        console.log(a.repeat('he'));  // ""  字符串输出空值
        console.log(a.repeat('2')); // 参数如果是字符串，会先转换数字

        console.log('padStart() padEnd() 字符串补全');
        /* 实例方法 padStart() padEnd() 字符串补全
        padStart() 头部补全
        padEnd() 尾部补全  
        */
        let b = 'how'
        console.log(b.padStart(5,'aa')); // 字符串长度补到5位，在how头部补全aa
        console.log(b.padStart(5,'aba')); // 字符串长度补到5位，在how头部补全ab，补全的字符串超出会被截取
        console.log(b.padEnd(5,'aa'));  // 字符串长度补到5位，在how尾部补全aa
        console.log(b.padEnd(5,'aba')); // 字符串长度补到5位，在how尾部补全ab，补全的字符串超出会被截取
        console.log(b.padStart(5));  // 如果省略第二个参数则用空格代替  "   how"
        console.log(b.padEnd(5));  // 如果省略第二个参数则用空格代替  "how   "
        // padStart常见的使用场景
        console.log('1'.padStart(5,'0'));  // 补全数字  00001
        console.log('09-12'.padStart(10,'YYYY-MM-DD'));  // 提示字符串格式 YYYY-09-12
    


        console.log('========消除空格==============');
        /* 消除空格 */
        let s = ' abc  '
        console.log(s.trim()); // 消除首尾空格   'abc'
        console.log(s.trimStart()); // 消除头部空格  'abc  '
        console.log(s.trimEnd()); // 消除尾部空格 '  abc'


        console.log('=====replaceAll()=========');
        /* replaceAll() */
        /* 一般使用的replace() 只能替换第一个匹配的字符 */
        console.log('hello'.replace('l', 'o')); // heolo  只替换了第一个

        /* 如果要匹配所有，就需要使用正则表达式的 g 修饰符 */
        console.log('hello'.replace(/l/g, 'o')); // heooo  替换所有

        /* 这里提供了一个更加方便的方法，es2021引入了replaceAll(),可以匹配所有并替换 */
        let r = 'green'
        console.log(r.replaceAll('e', 'n')); // grnnn  匹配所有e替换为n
        console.log(r); // green
        /* ***replace和replaceAll()会返回新的字符，不会影响原字符*** */

        /* replaceAll()为替换所有，如果在第一个参数中使用正则表达式，需要/g，g为全局，否则报错 */
        // console.log('hello'.replaceAll(/l/,'o'));   // 报错

        console.log('=========replaceAll()特殊字符串=========');
        /* replaceAll()
           接收两个参数，第二个参数是字符串，这里提供了一些特殊字符串
           $&   匹配的字符串  
           $`   匹配结果前面的文本
           $'   匹配结果后面的文本
           $n   匹配成功的n组内容，n是从1开始的自然数。这个参数生效的前提是，第一个参数必须是正则表达式。
           $$   指代美元符号$。
        */
        console.log('hello'.replaceAll('e', '$&')); // hello 返回结果与原字符一致
        console.log('hello'.replaceAll('l', '$`')); // hehehelo 将l替换成l前面的字符，这里有两个l,第一个l被替换成he，第二个l被替换成hehe
        console.log('hello'.replaceAll('l', `$'`)); // helooo 将l替换成l后面的字符，这里有两个l,第一个l被替换成lo，第二个l被替换成o
        console.log('---');
        console.log('hello'.replaceAll(/(he)(llo)/g,
            '$2$1'
        )) //llohe $后面的x就是第几个匹配， $2等于llo $1等于el，这里相当于是吧llo放到了前面，he放到了后面,这种匹配方式必须是字符串的等长匹配，如果是/(he)(lo)/g,'$2$1'不会生效，因为匹配的字符串长度与原字符串长度不符。

        /* replaceAll()的第二个参数可以是一个函数 */
        console.log('hello'.replaceAll('l', () => 'o')); // heooo 替换所有的l为o

        console.log('====组和函数匹配====');
        /* 组和函数匹配
           这个替换函数可以接受多个参数。第一个参数是捕捉到的匹配内容，第二个参数捕捉到是组匹配（有多少个组匹配，就有多少个对应的参数）。此外，最后还可以添加两个参数，倒数第二个参数是捕捉到的内容在整个字符串中的位置，最后一个参数是原字符串。
        */
        let str = '123hello456'
        let regex = /(\d+)([a-z]+)(\d+)/g // 有三个组，组1匹配数字，组2匹配字母，组3匹配数字
        // all为传入的字符串123hello456，z1\z2\z3为对应的组
        function replacer(all, z1, z2, z3, offset, string) {
            return [z1, z2, z3].join('-') // 将匹配的内容用 - 连接
        }
        let re = str.replaceAll(regex, replacer)
        console.log(re); //123-hello-456


        console.log('========at()============');
        console.log('hello'.at(2)); // 输出l 字符串中第0位开始，输出下标2的字符
        console.log('hello'.at(-1)); // 输出o,从末尾开始，第1位开始，输出下标1的字符
    </script>
</body>

</html>